﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DiscoveryLogic.DataViz.NetworkDiagram.NetworkData;

namespace DiscoveryLogic.DataViz.NetworkDiagram.QueryControls
{
    /// <summary>
    /// 
    /// </summary>
    public partial class LinkageFilter : UserControl
    {
        private readonly List<Network> _Networks;
        private readonly List<LinkDataObject> _LinkDOs;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="linkTypes"></param>
        /// <param name="minDistance"></param>
        /// <param name="maxDistance"></param>
        public delegate void OnLinkageFilterUpdated(List<LinkType> linkTypes, double minDistance, double maxDistance);
        /// <summary>
        /// 
        /// </summary>
        public event OnLinkageFilterUpdated LinkageFilterUpdated;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="networks"></param>
        /// <param name="linkDOs"></param>
        public LinkageFilter(List<Network> networks, List<LinkDataObject> linkDOs)
        {
            this._Networks = networks;
            this._LinkDOs = linkDOs;
            InitializeComponent();
        }

        private void LinkageFilter_Load(object sender, EventArgs e)
        {
            this.cbo_FromNetwork.Items.Clear();
            this.cbo_ToNetwork.Items.Clear();
            this.cbo_Networks.Items.Clear();
            this.clb_LinkTypes.Items.Clear();
            List<LinkType> linkTypes=new List<LinkType>();
            foreach(Network network in this._Networks)
            {
                this.cbo_FromNetwork.Items.Add(network.NetworkName);
                this.cbo_ToNetwork.Items.Add(network.NetworkName);
                this.cbo_Networks.Items.Add(network.NetworkName);

                if(!linkTypes.Contains(network.RelationType))
                    linkTypes.Add(network.RelationType);
            }
            
            double minDistance = double.PositiveInfinity;
            double maxDistance = 0;
            if(this._LinkDOs !=null && this._LinkDOs.Count>0)
            {
                foreach(LinkDataObject link in this._LinkDOs)
                {
                    if(link.Distance > maxDistance)
                        maxDistance = link.Distance;
                    if(link.Distance < minDistance)
                        minDistance = link.Distance;
                    if(!linkTypes.Contains(link.RelationType))
                        linkTypes.Add(link.RelationType);
                }

                this.num_From.Minimum = (decimal)minDistance;
                this.num_From.Maximum = (decimal)maxDistance;
                this.num_From.Value = (decimal)minDistance;
                this.num_To.Minimum = (decimal)minDistance;
                this.num_To.Maximum = (decimal)maxDistance;
                this.num_To.Value = (decimal)maxDistance;
            }

            foreach (LinkType linktype in linkTypes)
            {
                this.clb_LinkTypes.Items.Add(linktype.ToString());
            }
            
        }

        private void rd_Network_CheckedChanged(object sender, EventArgs e)
        {
            if(this.rd_Network.Checked)
            {
                this.cbo_Networks.Enabled = true;
                this.cbo_FromNetwork.Enabled = false;
                this.cbo_ToNetwork.Enabled = false;
            }
            else if(this.rd_Link.Checked)
            {
                this.cbo_Networks.Enabled = false;
                this.cbo_FromNetwork.Enabled = true;
                this.cbo_ToNetwork.Enabled = true;
            }
        }

        private void clb_LinkTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.UpdateLinkageFilter();
        }

        private void num_From_ValueChanged(object sender, EventArgs e)
        {
            this.UpdateLinkageFilter();
        }

        private void num_To_ValueChanged(object sender, EventArgs e)
        {
            this.UpdateLinkageFilter();
        }

        private void UpdateLinkageFilter()
        {
            List<LinkType> linkTypes=new List<LinkType>();
            for(int i=0;i<this.clb_LinkTypes.Items.Count;i++)
            {
                if(this.clb_LinkTypes.GetItemChecked(i))
                {
                    LinkType linkType = (LinkType) Enum.Parse(typeof (LinkType), this.clb_LinkTypes.Items[i].ToString());
                    linkTypes.Add(linkType);
                }
            }
            double minDistance =(double) this.num_From.Value;
            double maxDistance = (double)this.num_To.Value;
            if (this.LinkageFilterUpdated != null)
                this.LinkageFilterUpdated(linkTypes, minDistance, maxDistance);
        }
    }
}
